xend: pass-through: use devfn instead of slots as the unit for pass-through
authorKeir Fraser <keir.fraser@citrix.com>
Sat, 27 Jun 2009 08:51:37 +0000 (09:51 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Sat, 27 Jun 2009 08:51:37 +0000 (09:51 +0100)
Instead of suppling a slot number to qemu-xen, supply a devfn.

This and subsequent other changes will allow xend to ask
for more than one function to be inserted into a single slot -
by specifying which function of the slot should be used.

This is a minimal patch for this change. A subsequent
patch that has a lot of noise to rename slot to devfn
is intended to follow.

Cc: Dexuan Cui <dexuan.cui@intel.com>
Cc: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
tools/python/xen/util/pci.py
tools/python/xen/xend/XendConfig.py
tools/python/xen/xend/XendConstants.py
tools/python/xen/xend/XendDomainInfo.py
tools/python/xen/xend/server/pciif.py
tools/python/xen/xm/main.py

index b990b91cbd470c6c4dd2f6ed98528db3e13cfbd1..dc8dc64a7a4d83faf6b9b8eae4d01edbd7e86a40 100644 (file)
@@ -16,7 +16,7 @@ import threading
 from xen.util import utils
 from xen.xend import uuid
 from xen.xend import sxp
-from xen.xend.XendConstants import AUTO_PHP_SLOT
+from xen.xend.XendConstants import AUTO_PHP_DEVFN
 from xen.xend.XendSXPDev import dev_dict_to_sxp
 
 PROC_PCI_PATH = '/proc/bus/pci/devices'
@@ -115,6 +115,10 @@ PAGE_MASK=~(PAGE_SIZE - 1)
 # Definitions from Linux: include/linux/pci.h
 def PCI_DEVFN(slot, func):
     return ((((slot) & 0x1f) << 3) | ((func) & 0x07))
+def PCI_SLOT(devfn):
+    return (devfn >> 3) & 0x1f
+def PCI_FUNC(devfn):
+    return devfn & 0x7
 
 def PCI_BDF(domain, bus, slot, func):
     return (((domain & 0xffff) << 16) | ((bus & 0xff) << 8) |
@@ -246,9 +250,9 @@ def parse_pci_name_extended(pci_dev_str):
     out['slot']   = "0x%02x" % int(pci_dev_info['slot'], 16)
     out['func']   = "0x%x"   % int(pci_dev_info['func'], 16)
     if pci_dev_info['vslot'] == '':
-        vslot = AUTO_PHP_SLOT
+        vslot = AUTO_PHP_DEVFN
     else:
-        vslot = int(pci_dev_info['vslot'], 16)
+        vslot = PCI_DEVFN(int(pci_dev_info['vslot'], 16), 0)
     out['vslot'] = "0x%02x" % vslot
     if pci_dev_info['opts'] != '':
         out['opts'] = split_pci_opts(pci_dev_info['opts'])
@@ -259,10 +263,11 @@ def parse_pci_name_extended(pci_dev_str):
 def parse_pci_name(pci_name_string):
     pci = parse_pci_name_extended(pci_name_string)
 
-    if int(pci['vslot'], 16) != AUTO_PHP_SLOT:
+    if int(pci['vslot'], 16) != AUTO_PHP_DEVFN:
         raise PciDeviceParseError(("Failed to parse pci device: %s: " +
-                                   "vslot provided where prohibited: %s") %
-                                  (pci_name_string, pci['vslot']))
+                                   "vslot provided where prohibited: 0x%02x") %
+                                  (pci_name_string,
+                                   PCI_SLOT(int(pci['vslot'], 16))))
     if 'opts' in pci:
         raise PciDeviceParseError(("Failed to parse pci device: %s: " +
                                    "options provided where prohibited: %s") %
index 9cced961a8298866b998df891bef65608bcd2d38..8842a902ad773d1b7aa17279748ea81e3e95a56b 100644 (file)
@@ -32,7 +32,7 @@ from xen.xend.XendDSCSI import XendDSCSI
 from xen.xend.XendError import VmError
 from xen.xend.XendDevices import XendDevices
 from xen.xend.PrettyPrint import prettyprintstring
-from xen.xend.XendConstants import DOM_STATE_HALTED, AUTO_PHP_SLOT_STR
+from xen.xend.XendConstants import DOM_STATE_HALTED, AUTO_PHP_DEVFN_STR
 from xen.xend.xenstore.xstransact import xstransact
 from xen.xend.server.BlktapController import blktap_disk_types
 from xen.xend.server.netif import randomMAC
@@ -1250,7 +1250,7 @@ class XendConfig(dict):
                 'VM': self['uuid'],
                 'PPCI': ppci_uuid,
                 'hotplug_slot': pci_dev.get('vslot',
-                                            '0x' + AUTO_PHP_SLOT_STR)
+                                            '0x' + AUTO_PHP_DEVFN_STR)
             }
 
             dpci_opts = pci_dev.get('opts')
index c25ba2935a39df9de912b8fd78a84e71f5828f34..588470ab69d0480ed00dc4d69a904e0bb30c8189 100644 (file)
@@ -138,9 +138,11 @@ VTPM_DELETE_SCRIPT = auxbin.scripts_dir() + '/vtpm-delete'
 
 XS_VMROOT = "/vm/"
 
+NR_PCI_FUNC = 8
 NR_PCI_DEV = 32
-AUTO_PHP_SLOT = NR_PCI_DEV
-AUTO_PHP_SLOT_STR = "%02x" % NR_PCI_DEV
+NR_PCI_DEVFN = NR_PCI_FUNC * NR_PCI_DEV
+AUTO_PHP_DEVFN = NR_PCI_DEVFN
+AUTO_PHP_DEVFN_STR = "%02x" % NR_PCI_DEVFN
 
 #
 # tmem
index f943675292bcdb05c20574a387a7ab0371f21ea1..ee38023c1a16898e500475135f09fe3343004d4b 100644 (file)
@@ -644,7 +644,7 @@ class XendDomainInfo:
             pci_devs = pci_conf['devs']
             for x in pci_devs:
                 if (int(x['vslot'], 16) == int(new_dev['vslot'], 16) and
-                   int(x['vslot'], 16) != AUTO_PHP_SLOT):
+                   int(x['vslot'], 16) != AUTO_PHP_DEVFN):
                     raise VmError("vslot %s already have a device." % (new_dev['vslot']))
 
                 if (pci_dict_cmp(x, new_dev)):
index da768f2ad9dc77a7ee89c1a7f8d710a425a1506e..1b3a2cf29c26fc9aae302e3f4ef59a3dc616ceaf 100644 (file)
@@ -75,7 +75,7 @@ class PciController(DevController):
             slot = parse_hex(pci_config.get('slot', 0))
             func = parse_hex(pci_config.get('func', 0))            
             vslot = parse_hex(pci_config.get('vslot',
-                                             '0x' + AUTO_PHP_SLOT_STR))
+                                             '0x' + AUTO_PHP_DEVFN_STR))
 
             if pci_config.has_key('opts'):
                 opts = serialise_pci_opts(pci_config['opts'])
index 966e2733d0a43218c9be6003cf23566a048c1b28..9688ba3d97079035d2387acc67bf0f436412bb40 100644 (file)
@@ -2214,17 +2214,19 @@ def xm_pci_list(args):
 
     has_vslot = False
     for x in devs:
-        if x['vslot'] == AUTO_PHP_SLOT:
+        if x['vslot'] == AUTO_PHP_DEVFN:
             x['show_vslot'] = '-'
+            x['show_vfunc'] = '-'
         else:
-            x['show_vslot'] = "0x%02x" % x['vslot']
+            x['show_vslot'] = "0x%02x" % PCI_SLOT(x['vslot'])
+            x['show_vfunc'] = "0x%x" % PCI_FUNC(x['vslot'])
             has_vslot = True
 
     hdr_str = 'domain bus  slot func'
     fmt_str = '0x%(domain)04x 0x%(bus)02x 0x%(slot)02x 0x%(func)x'
     if has_vslot:
-        hdr_str = 'VSlt ' + hdr_str
-        fmt_str = '%(show_vslot)-4s ' + fmt_str
+        hdr_str = 'VSlt VFn ' + hdr_str
+        fmt_str = '%(show_vslot)-4s %(show_vfunc)-3s ' + fmt_str
 
     print hdr_str
     for x in devs:
@@ -2520,7 +2522,6 @@ def xm_pci_attach(args):
                      config_pci_opts)
 
     if serverType == SERVER_XEN_API:
-
         pci_dev = sxp.children(pci, 'dev')[0]
         domain = int(sxp.child_value(pci_dev, 'domain'), 16)
         bus = int(sxp.child_value(pci_dev, 'bus'), 16)